﻿using System;
using System.Collections.Generic;
using System.Text;
using PreguntaAlExperto.TransporterObjectsFramework;
using PreguntaAlExperto.RulesLayer.Entities;
using PreguntaAlExperto.ObjectMapper;
using PreguntaAlExperto.ObjectMapper.DTO;
using PreguntaAlExperto.ObjectMapper.Helper;
using Common;
using PreguntaAlExperto.Tools;

namespace PreguntaAlExperto.RulesLayer.Services
{
    public class PublisherService
    {
        public Publisher getPublisherByID(int Publisher_ID)
        {
            SearchCriteria _searchCriteria = new SearchCriteria();
            _searchCriteria.addParameter("@Publisher_ID", Publisher_ID);

            PublisherDTO _DTO = new PublisherDTO();
            return ((BaseList<Publisher>)(_DTO.Select("SQL_PUBLISHER_BY_ID", _searchCriteria)))[0];
        }

        public Publisher registerNewUser(Publisher _publisher)
        {
            SearchCriteria _searchCriteria = new SearchCriteria();
            _searchCriteria.addParameter("@USERNAME", _publisher.Username);

            SingleValueDTO _DTO = new SingleValueDTO();

            if (((int)_DTO.Select("SQL_CHECK_PUBLISHER_NICKNAME", _searchCriteria)) != 0)
                throw new Exception("Nombre de usuario existente.");

            _searchCriteria.clearParameters();
            _searchCriteria.addParameter("@EMAIL", _publisher.Email);
            if (((int)_DTO.Select("SQL_CHECK_PUBLISHER_EMAIL", _searchCriteria)) != 0)
                throw new Exception("Correo electrónico existente.");

            _searchCriteria.clearParameters();

            Guid _guid = Guid.NewGuid();
            EncryptionServices _encoder = new EncryptionServices();
            _publisher.Password = _encoder.EncodeStringToMD5(_publisher.Password);
            _searchCriteria.addParameter("@NAME",_publisher.Name);
            _searchCriteria.addParameter("@USERNAME",_publisher.Username);
            _searchCriteria.addParameter("@PASSWORD",_publisher.Password);
            _searchCriteria.addParameter("@EMAIL",_publisher.Email);
            _searchCriteria.addParameter("@AutenticationKey", _guid.ToString());
            
            _publisher.ID_Publisher = ((int)_DTO.Select("SQL_INSERT_PUBLISHER",_searchCriteria));

            SearchCriteria _mailCriteria = new SearchCriteria();
            _mailCriteria.addParameter("@Publisher_Name", _publisher.Username);
            _mailCriteria.addParameter("@Password", _publisher.Password);
            _mailCriteria.addParameter("@AuthenticationKey", _guid.ToString());

            MailHandler _mail = new MailHandler(enuMailType.NewUserMail,
                _mailCriteria, 
                "Registro y confirmación en Pregunta Al Experto.net", 
                _publisher.Email);
            _mail.SendMail();

            return _publisher;
        }

        public Publisher logUser(Publisher _publisher)
        {
            PublisherDTO _DTO = new PublisherDTO();
            EncryptionServices _encoder = new EncryptionServices();
            SearchCriteria _searchCriteria = new SearchCriteria();
            _searchCriteria.addParameter("@USERNAME", _publisher.Username);
            _searchCriteria.addParameter("@PASSWORD", _encoder.EncodeStringToMD5(_publisher.Password));

            BaseList<Publisher> _publisherCollection = ((BaseList<Publisher>)(_DTO.Select("SQL_SELECT_PUBLISHER", _searchCriteria)));

            if (_publisherCollection.Count == 0)
                throw new LoginException("Nombre de usuario o contraseña incorrectos.");

            _publisher.ID_Publisher = _publisherCollection[0].ID_Publisher;
            _publisher.Name = _publisherCollection[0].Name;
            _publisher.Member = _publisherCollection[0].Member;
            _publisher.Password = "";
            return _publisher;
        }

        public string resetPublisher(string _email)
        {
            SearchCriteria _searchCriteria = new SearchCriteria();
            _searchCriteria.addParameter("@EMAIL", _email);

            PublisherDTO _DTO = new PublisherDTO();
            BaseList<Publisher> _publisherCollection = ((BaseList<Publisher>)_DTO.Select("SQL_GET_PUBLISHER_BY_EMAIL", _searchCriteria));
            if (_publisherCollection.Count >= 1)
            {
                _searchCriteria.clearParameters();
                Publisher _publisher = _publisherCollection[0];
                //Guid _newGuid = Guid.NewGuid();
                EncryptionServices _encoder = new EncryptionServices();
                PasswordGenerator _passGenerator = new PasswordGenerator();
                _passGenerator.MaxLength = 20;
                _passGenerator.MinLength = 6;
                string _newPassword = _passGenerator.Generate(); //_newGuid.ToString();
                _publisher.Password = _encoder.EncodeStringToMD5(_newPassword);

                _searchCriteria.addParameter("@PUBLISHER_ID", _publisher.ID_Publisher);
                _searchCriteria.addParameter("@PASSWORD", _publisher.Password);
                _DTO.Update("SQL_UPDATE_PUBLISHER_PASSWORD", _searchCriteria);

                return _newPassword;
            }
            else
                return string.Empty;
        }

        public bool InsertGeneralComment(string _comment)
        {
            List<SearchCriteria> _searchList = new List<SearchCriteria>();
            List<string> _queries = new List<string>();
            SearchCriteria _searchCriteria = new SearchCriteria();
            _searchCriteria.addParameter("@Comments", _comment);

            _queries.Add("SQL_INSERT_GENERAL_COMMENT");
            _searchList.Add(_searchCriteria);

            CommentsDTO _DTO = new CommentsDTO();
            try
            {
                _DTO.AdvancedActualization(_queries, _searchList);
            }
            catch
            {
                return false;
            }
            return true;
        }

        public Publisher AutenticatePublisher(string guid)
        { 
            PublisherDTO _DTO = new PublisherDTO();
            SearchCriteria _searchCriteria = new SearchCriteria();
            _searchCriteria.addParameter("@Key", guid);
            int _recordsAffected = _DTO.Update("SQL_UPDATE_AUTENTICATED_PUBLISHER", _searchCriteria);

            if (_recordsAffected != 0)
            {
                return ((BaseList<Publisher>)(_DTO.Select("SQL_PUBLISHER_BY_KEY", _searchCriteria)))[0];
            }
            else
            { return null; }
        }
    }
}
